package com.wenwen.social.domain.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.wenwen.social.common.exception.ServiceException;
import com.wenwen.social.domain.model.Medias;
import com.wenwen.social.domain.model.Message;
import com.wenwen.social.domain.service.MessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.wenwen.social.constant.MessageConstant.*;
import static com.wenwen.social.constant.errorcode.CommonErrorConstant.*;
import static java.util.stream.Collectors.toList;

@Service
@Slf4j
public class MessageServiceImpl implements MessageService{

	@Autowired
	RedisTemplate redisTemplate;

	@Override
	public Integer add(Message message) {
		try{
			HashOperations hashOperations = redisTemplate.opsForHash();
			String key = getKey(message.getId());
			Map<String, Object> stringObjectMap = BeanUtil.beanToMap(message);
			hashOperations.putAll(key,stringObjectMap);
			return 1;
		}catch (Exception e) {
			log.error("user save redis error.{}", JSONObject.toJSON(message), e);
			throw new ServiceException(SYSTEM_ERROR_CODE,SYSTEM_ERROR_MSG);
		}
	}

	@Override
	public Message query(Long msgId) {
		HashOperations hashOperations = redisTemplate.opsForHash();
		Map entries = hashOperations.entries(getKey(msgId));
		return BeanUtil.mapToBean(entries, Message.class,true);
	}

	@Override
	public List<Message> queryBatch(List<Long> msgIds) {
		List<Map> list = redisTemplate.executePipelined(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
				for (Long msgId : msgIds) {
					redisConnection.hGetAll(getKey(msgId).getBytes());
				}
				return null;
			}
		});
		if(list == null || list.isEmpty()){
			return new ArrayList<>();
		}

		return list.stream().map(t ->  BeanUtil.mapToBean(t,Message.class,true)).collect(toList());
	}

	@Override
	public Integer update(Message message) {
		return add(message);
	}

	@Override
	public Integer del(Message message) {
		HashOperations hashOperations = redisTemplate.opsForHash();
		Long msgId = message.getId();
		Object userIdObj = hashOperations.get(MESSAGE_REDIS_PRE + msgId, MESSAGE_UID);
		if(userIdObj == null){
			throw new ServiceException(MESSAGE_NOT_EXIST_CODE,MESSAGE_NOT_EXIST_MSG);
		}

		Long uid = ((Integer) userIdObj).longValue();
		if(uid== null) {
			throw new ServiceException(USER_NOT_EXIST_CODE,USER_NOT_EXIST_MSG);
		}
		if(!uid.equals(message.getUid())){
			throw new ServiceException(MESSAGE_NOT_EXIST_CODE,MESSAGE_NOT_EXIST_MSG);
		}
		Map<String, Object> maps = BeanUtil.beanToMap(message);
		Set<String> keys = maps.keySet();
		Long delete = hashOperations.delete(getKey(msgId),keys.toArray());
		return delete.intValue()/keys.size();
	}

	private String getKey(Long msgId){
		return MESSAGE_REDIS_PRE+msgId;
	}
}
